package cz.acies.uniql.sql.element;

import org.dom4j.Element;
import org.dom4j.dom.DOMElement;


import cz.acies.uniql.dialect.Dialect;
import cz.acies.uniql.metadata.DBMetaData;
import cz.acies.uniql.sql.Query;
import cz.acies.uniql.sql.SelectQuery;
import cz.acies.uniql.sql.UniQLExpr;

public class UniQLSubQuery extends Query
{
	private static final long serialVersionUID = -8398513720832501704L;
	
	private SelectQuery select;
	private String alias;

	/**
	 * Konstruktor tridy UniQLSubQuery
	 */
	public UniQLSubQuery() {
	}

	/**
	 * Konstruktor tridy UniQLSubQuery
	 * @param dialect
	 */
	public UniQLSubQuery(Dialect dialect, DBMetaData dbmd) {
		super(dialect, dbmd);
	}

	/**
	 * Konstruktor tridy UniQLSubQuery.
	 * @param select
	 */
	public UniQLSubQuery(SelectQuery select) {
		super();
		if (select != null) {			
			if (select.getDialect() != null) {
				this.setDialect(select.getDialect());
			}
			this.select = select;
		}
	}

	/**
	 * Konstruktor vytvori nonou instanci objektu UniQLWhere s vlastnostmi
	 * objektu zadaneho jako parametr konstruktoru.
	 *  
	 * @param orderBy
	 */
	public UniQLSubQuery(UniQLSubQuery expr) throws Exception {
		this();
		UniQLSubQuery clone = (UniQLSubQuery) expr.clone();
		
		setId(clone.getId());
		setName(clone.getName());
		setDialect(clone.getDialect());
		setAliasMap(clone.getAliasMap());

		setAlias(clone.getAlias());
		setSelect(clone.getSelect());
	}

	// -----  -----------------------------------------------------------------
	
	/**
	 * Funkce transformuje objekt UniQLExpr na String v z�vislosti na typu dialektu
	 * 
	 * @return
	 * Funkce transformuje objekt UniQLExpr na String v z�vislosti na typu dialektu
	 */
	public String translate() throws Exception {
		StringBuffer sb = new StringBuffer();
		getSelect().setUniQLProperties(this);
		sb.append("("+"\n").append(getSelect().translate()).append("\n"+")");
		String alias = this.getAlias(); 
		if (alias != null && alias.length() > 0) {
			sb.append(this.getDialect().getFromAsString()+alias);
		}
		return sb.toString();
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#clone()
	 */
	@Override
	public Object clone() throws CloneNotSupportedException {
		Object clone = super.clone();
		assert clone instanceof UniQLSubQuery;
		((UniQLSubQuery) clone).setSelect(((getSelect() != null) ? (SelectQuery)select.clone() : null));
		((UniQLSubQuery) clone).setAlias(alias);
		return clone;
	}

	public String toSQLString() throws Exception {
		return this.translate();
	}
		
	/**
	 * Funkce p�etransformuje �et�zec sql na objekt type UniQLExpr
	 * @param sql - 
	 * @return
	 */
	public UniQLExpr parse(String sql) {
		return this;
	}

	// ----- Getter & setter methods ------------------------------------------

	public SelectQuery getSelect() {
		if (select == null) {
			select = new SelectQuery();
			select.setDialect(this.getDialect());
		}
		return select;
	}

	public UniQLSubQuery setSelect(SelectQuery select) {
		this.select = select;
		return this;
	}

	/**/
	
	public String getAlias() {
		return alias;
	}

	public UniQLSubQuery setAlias(String alias) {
		this.alias = alias;
		return this;
	}

	public UniQLSubQuery as(String alias) {
		this.alias = alias;
		return this;
	}
	
	// -----  -----------------------------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#transToXML()
	 */
	public String transToXML() throws Exception {
		DOMElement node = new DOMElement("UniQLSubQuery");
		transToXML(node);
		return node.asXML();
	}
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#transToXML(org.dom4j.dom.DOMElement)
	 */
	public DOMElement transToXML(DOMElement node) throws Exception {
		if (this.getSelect() != null) {
			node = this.getSelect().transToXML(node);
			node.setName("UniQLSubQuery");
			//System.out.println("UniQLSubQuery.transToXML().xml = "+node.asXML());
		}
		return node;
	}
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#xmlToExpr(java.lang.String)
	 */
	public UniQLExpr xmlToExpr(String xml) throws Exception {
		System.out.println("UniQLJoin.xmlToExpr(xml)");
		return null;
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#xmlToExpr(org.dom4j.Element)
	 */
	public UniQLExpr xmlToExpr(Element node) throws Exception {
		if (node.getName().equals("UniQLSubQuery")) {
			node.setName("SelectQuery");
			SelectQuery query = new SelectQuery();
			query.xmlToExpr(node);
			this.setSelect(query);
		}
		return this;
	}

}
